package com.xiaomaoguai.fcp.YND.test;

import com.xiaomaoguai.fcp.kepler.utils.Base64Utils;
import lombok.extern.slf4j.Slf4j;

import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESKeySpec;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.security.spec.InvalidKeySpecException;

@Slf4j
public class DesUtil {

    private final static String DES = "DES";

    /**
     * Description 根据键值进行加密
     *
     * @param data
     * @param key
     *            加密键byte数组
     * @return
     * @throws Exception
     */
    public static byte[] encryptBytes(byte[] data, byte[] key) throws Exception {
        return encrypt(data, key);
    }

    /**
     * Description 根据键值进行加密
     *
     * @param data
     * @param key
     *            加密键byte数组
     * @return
     * @throws Exception
     */
    public static String encrypt(String data, String key){
        byte[] bt = encrypt(data.getBytes(), key.getBytes());
        return Base64Utils.encode(bt);
    }

    /**
     * Description 根据键值进行解密
     *
     * @param data
     * @param key
     *            加密键byte数组
     * @return
     * @throws Exception
     */
    public static String decrypt(String data, String key) throws Exception {

        if (data == null)
            return null;
        byte[] buf = Base64Utils.decode(data);
        byte[] bt = decrypt(buf, key.getBytes());
        return new String(bt);
    }
    /**
     * Description 根据键值进行解密
     *
     * @param data
     * @param key
     *            加密键byte数组
     * @return
     */
    public static byte[] decryptBytes(byte[] data, byte[] key){
        return decrypt(data, key);


    }

    /**
     * Description 根据键值进行加密
     *
     * @param data
     * @param key
     *            加密键byte数组
     * @return
     * @throws Exception
     */
    public static byte[] encrypt(byte[] data, byte[] key){

        byte[] encryptData = null;

        try {
            SecureRandom sr = new SecureRandom(); // 生成一个可信任的随机数源
            DESKeySpec dks = new DESKeySpec(key);   // 从原始密钥数据创建DESKeySpec对象

            // 创建一个密钥工厂，然后用它把DESKeySpec转换成SecretKey对象
            SecretKeyFactory keyFactory = SecretKeyFactory.getInstance(DES);
            SecretKey securekey = keyFactory.generateSecret(dks);

            Cipher cipher = Cipher.getInstance(DES);  // Cipher对象实际完成加密操作
            cipher.init(Cipher.ENCRYPT_MODE, securekey, sr);  // 用密钥初始化Cipher对象

            encryptData = cipher.doFinal(data);
        }catch (InvalidKeyException | NoSuchAlgorithmException | InvalidKeySpecException
            | NoSuchPaddingException | IllegalBlockSizeException | BadPaddingException e){

            log.error("des加密异常", e);
        }
        return encryptData;
    }

    /**
     * Description 根据键值进行解密
     * @param data
     * @param key
     *            加密键byte数组
     * @return
     * @throws Exception
     */
    private static byte[] decrypt(byte[] data, byte[] key) {

        SecureRandom sr = new SecureRandom();  // 生成一个可信任的随机数源
        byte[] originData = null;
        try {
            DESKeySpec dks = new DESKeySpec(key);  // 从原始密钥数据创建DESKeySpec对象

            // 创建一个密钥工厂，然后用它把DESKeySpec转换成SecretKey对象
            SecretKeyFactory keyFactory = SecretKeyFactory.getInstance(DES);
            SecretKey securekey = keyFactory.generateSecret(dks);

            Cipher cipher = Cipher.getInstance(DES); // Cipher对象实际完成解密操作
            cipher.init(Cipher.DECRYPT_MODE, securekey, sr);  // 用密钥初始化Cipher对象

            originData = cipher.doFinal(data);

        }catch (InvalidKeyException | NoSuchAlgorithmException | InvalidKeySpecException
            | NoSuchPaddingException | IllegalBlockSizeException | BadPaddingException e){

            log.error("des解密异常", e);
        }

        return originData;
    }


    public static void main(String[] args) throws Exception {

        String s = "nihao你好,。hello！";
        String key = "fd6b65de3c826c385edc0705d27bc1bf";
        String enStr = encrypt(s, key);
        System.out.println("--------enStr=" + enStr);

        String deStr = decrypt(enStr, "fd6b65de3c826c385edc0705d27bc1bf");
        System.out.println("--------deStr=" + deStr);

    }

}
